package com.wunong.smart.commission.domain.state.operation;

import com.google.common.base.Preconditions;
import com.wunong.smart.commission.application.context.CommissionContext;
import com.wunong.smart.commission.application.request.BaseCommissionRequest;
import com.wunong.smart.commission.domain.model.CommissionDomain;
import com.wunong.smart.commission.domain.repository.CommissionRepository;
import com.wunong.smart.domain.platform.common.VerifyDTO;
import com.wunong.smart.domain.platform.exception.IllegalOperateException;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.Resource;

/**
 * @author create by zealot.zt
 */
@Slf4j
public abstract class AbstractCommissionOperation<REQ extends BaseCommissionRequest> implements CommissionOperation<REQ> {

    @Resource
    protected CommissionRepository commissionRepository;

    @Override
    public Object operate(CommissionContext<REQ> context) {
        beforeExecute(context);

        VerifyDTO verifyDTO = canOperate(context);
        Preconditions.checkArgument(verifyDTO != null, "参数非法，不支持拼团活动操作");
        if (verifyDTO.isNonAccess()) {
            return getCannotOperateResult(context, verifyDTO);
        }

        Object result = doOperate(context);
        afterExecute(context, result);
        return result;
    }

    /**
     * 获取不能操作时的结果
     *
     * @param context
     * @param verifyDTO
     * @return
     */
    protected Object getCannotOperateResult(CommissionContext<REQ> context, VerifyDTO verifyDTO) {
        CommissionDomain model = context.getModel();
        log.error("{} commission failed, user:{}, id:{}", getOperationEnum(), model.getUser(), model.getId());
        throw new IllegalOperateException(getOperationEnum().getName() + "失败，" + verifyDTO.getTips());
    }

    protected void beforeExecute(CommissionContext<REQ> context) {
        // do nothing
    }

    /**
     * 执行对应的操作
     *
     * @param context
     * @return
     */
    protected abstract Object doOperate(CommissionContext<REQ> context);

    /**
     * 操作成功，记录对应的动作记录
     *
     * @param context
     * @param result
     */
    protected void afterExecute(CommissionContext<REQ> context, Object result) {
        // do nothing
    }

}
